/* N2kStream.h
 * Copyright (c) 2015-2023 Timo Lappalainen, Kave Oy, www.kave.fi
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
*/

/**************************************************************************//**
 * \file  N2kStream.h
 * \brief This File contains an I/O stream used in the NMEA2000 libraries.
 * 
 * 
 * Arduino users get away with using the standard Stream class and its
 * subclasses. Forward declare the Stream class here and include Arduino.h in
 * the application.  (\#define ARDUINO)
 *  
 * Non Arduino platforms need to implement this themselves if they want to use
 * functions which operate on streams.
 * 
 */

#ifndef _tN2kStream_H_
#define _tN2kStream_H_

#include "N2kDef.h"
#include <stdint.h>
#include <stddef.h>

#ifdef ARDUINO
// Arduino users get away with using the standard Stream class and its
// subclasses. Forward declare the Stream class here and include Arduino.h in
// the application.
#include <Arduino.h>
/** Brief Forward Declaration of the stream class*/
typedef Stream N2kStream;
#else

/**************************************************************************//**
 * \class N2kStream
 * \brief Streaming Class to handle all Streams generated by the Library
 * \ingroup group_coreSupplementary
 * 
 * Non Arduino platforms need to implement this class if they want to use
 * functions which operate on streams. 
 */
class N2kStream {
   public:
   /************************************************************************//**
    * \brief reads characters from an incoming stream to the buffer
    * 
    * \return  The first byte of incoming data available (or -1 if no data
    *          is available)
    */
   virtual int read() = 0;
   /***********************************************************************//**
    * \brief reads a byte from the file without advancing to the next one
    * 
    * \return int The next byte (or character), or -1 if none is available
    */
   virtual int peek() = 0;

   /***********************************************************************//**
    * \brief  Write data to stream.
    * 
    * \param data    uint8 Array of Data for the stream
    * \param size    size of the Data
    * \return size_t 
    */
   virtual size_t write(const uint8_t* data, size_t size) = 0;

   /***********************************************************************//**
    * \brief Print string to stream.
    * 
    * \param str     String data for the stream
    * \return size_t 
    */
   size_t print(const char* str);

#if defined(__AVR__)
   // Flash stored string stream for AVR platforms.
   size_t print(const __FlashStringHelper* str);
   size_t println(const __FlashStringHelper* str);
#endif

   /***********************************************************************//**
    * \brief Print an value to the stream
    * 
    * \param val     Value for the stream
    * \param radix   Base format to be used (e.g. 10, 16, 8 ,2)
    * \return size_t 
    */
   size_t print(int val, uint8_t radix = 10);

   /***********************************************************************//**
    * \brief Print string and newline to stream.
    * 
    * \param str  String data for the stream
    * \return size_t 
    */
   size_t println(const char *str);

   /***********************************************************************//**
    * \brief Print value and newline to stream.
    * 
    * \param val     Value for the stream
    * \param radix   Base format to be used (e.g. 10, 16, 8 ,2)
    * \return size_t 
    */
   size_t println(int val, uint8_t radix = 10);
};
#endif

#endif
